package de.herberlin.contact;

import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.logging.Level;

import javax.swing.JOptionPane;

import org.w3c.dom.Document;

import de.herberlin.contact.ProgressListener.ProgressEvent;

/**
 * The Class Runner - runnable loads all contact files of the given directory,
 * parses each and writes the output file.
 */
public class Runner implements Runnable {

	/** The listener. */
	private ProgressListener listener = null;
	
	/** The target file. */
	private File sourceDir, targetFile;

	/**
	 * Instantiates a new runner.
	 * 
	 * @param listener the listener
	 * @param sourceDir the source dir
	 * @param targetFile the target file
	 */
	public Runner(ProgressListener listener, File sourceDir, File targetFile) {
		this.listener = listener;
		this.sourceDir = sourceDir;
		this.targetFile = targetFile;
	}

	/**
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {

		// get dir size
		File[] files = sourceDir.listFiles(new ContactFileFilter());
		if (files == null) {
			Manager.getLogger(this).log(Level.SEVERE,"Files must nut be null!");
			return;
		}
		boolean hasErrors = false;
		FileWriter out = null;
		try {
			out = new FileWriter(targetFile);
			for (int i = 0; i < files.length; i++) {
				fireEvent(files.length, i);
				try {
					Document doc = Manager.getDocumentBuilder().parse(files[i]);
					String txt = new Contact(doc).getAll();
					out.write(txt);
					out.write("\n");
					Manager.getLogger(this).log(Level.FINE,"Txt=" + txt);
				} catch (Exception e) {
					Manager.getLogger(this).log(Level.SEVERE,e.getMessage(), e);
					hasErrors = true;
				}
			}
		} catch (Exception ex) {
			Manager.getLogger(this).log(Level.SEVERE,ex.getMessage(), ex);
			hasErrors = true;
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					Manager.getLogger(this).log(Level.SEVERE,e.getMessage(), e);
				}
			}

		}
		fireEvent(files.length, files.length);
		if (hasErrors) {
			JOptionPane.showMessageDialog(null,
					"There where errors. Please see log for details.");
		}
	}

	/**
	 * Deliver progress information to the attached listener if any.
	 * 
	 * @param totalSize the total size
	 * @param current the current
	 */
	private void fireEvent(int totalSize, int current) {
		if (listener != null) {
			ProgressEvent evt = new ProgressEvent(totalSize, current);
			listener.progress(evt);
		}
	}

	/**
	 * The Class ContactFileFilter.
	 * Accepts files of typ .contact
	 */
	private static class ContactFileFilter implements FilenameFilter {

		/**
		 * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
		 */
		@Override
		public boolean accept(File dir, String name) {
			if (name != null && name.toLowerCase().endsWith(".contact")) {
				return true;
			}
			return false;
		}
	}
}
